// MFCRibbonFullscreenBar.cpp : implementation file
//

#include "stdafx.h"
//#include "full_screen.h"
#include "MFCRibbonFullscreenBar.h"
#include "RibbonFullscreenButton.h"
#include "BCGPRibbonBar.h"

// CMFCRibbonFullscreenBar

IMPLEMENT_DYNAMIC(CMFCRibbonFullscreenBar, CBCGPRibbonBar)

CMFCRibbonFullscreenBar::CMFCRibbonFullscreenBar()
{

}

CMFCRibbonFullscreenBar::~CMFCRibbonFullscreenBar()
{
	RemoveAll();
}


BEGIN_MESSAGE_MAP(CMFCRibbonFullscreenBar, CBCGPRibbonBar)
	ON_WM_CREATE()
	ON_WM_SIZE()
	ON_WM_ERASEBKGND()
	ON_WM_PAINT()
	ON_WM_SHOWWINDOW()
END_MESSAGE_MAP()



// CMFCRibbonFullscreenBar message handlers

BOOL CMFCRibbonFullscreenBar::Create(DWORD dwStyle, CWnd* pParentWnd, UINT uID)
{
	ASSERT_VALID(pParentWnd);   // must have a parent

	SetBarAlignment(CBRS_ALIGN_TOP);

	if (!CBCGPControlBar::Create(NULL, dwStyle, CRect(0, 0, 0, 0), pParentWnd, uID, 0))
	{
		return FALSE;
	}

	// register with parent frames' dock manager!!!
	if (pParentWnd->IsKindOf(RUNTIME_CLASS(CBCGPFrameWnd)))
	{
		((CBCGPFrameWnd*) pParentWnd)->AddControlBar(this);
	}
	else if (pParentWnd->IsKindOf(RUNTIME_CLASS(CMDIFrameWndEx)))
	{
		((CMDIFrameWndEx*) pParentWnd)->AddControlBar(this);
	}
	else if (pParentWnd->IsKindOf(RUNTIME_CLASS(CMDIChildWndEx)))
	{
		((CMDIChildWndEx*) pParentWnd)->AddControlBar(this);
	}
	else
	{
		ASSERT(FALSE);
		return FALSE;
	}

	return TRUE;
}


int CMFCRibbonFullscreenBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CBCGPRibbonBar::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  Add your specialized creation code here

	return 0;
}


void CMFCRibbonFullscreenBar::OnSize(UINT nType, int cx, int cy)
{
	CBCGPRibbonBar::OnSize(nType, cx, cy);

	RecalcLayout();
	RedrawWindow();
}


BOOL CMFCRibbonFullscreenBar::OnEraseBkgnd(CDC* pDC)
{
	// TODO: Add your message handler code here and/or call default

//	return CMFCRibbonBar::OnEraseBkgnd(pDC);
	return TRUE;
}


void CMFCRibbonFullscreenBar::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO: Add your message handler code here
	// Do not call CMFCRibbonBar::OnPaint() for painting messages

	CMemDC memDC(dc, this);
	CDC *pDc = &memDC.GetDC();

	CRect rectClip;
	dc.GetClipBox(&rectClip);

	CRgn rgnClip;
	if (!rectClip.IsRectEmpty())
	{
		rgnClip.CreateRectRgnIndirect(rectClip);
		pDc->SelectClipRgn(&rgnClip);
	}

	pDc->SetBkMode(TRANSPARENT);

	CRect rectClient;
	GetClientRect(rectClient);

	OnFillBackground(pDc, rectClient);

	CFont *pOldFont = pDc->SelectObject(GetFont());
	ENSURE(pOldFont != NULL);

	for (int i=0; i<(int)m_arElements.GetSize(); i++)
	{
		ASSERT_VALID(m_arElements[i]);
		m_arElements[i]->OnDraw(pDc);
	}

	for (int i = 0; i <(int) m_arExElements.GetSize(); i++)
	{
		ASSERT_VALID(m_arExElements [i]);
		m_arExElements [i]->OnDraw(pDc);
	}

	pDc->SelectObject(pOldFont);
	pDc->SelectClipRgn(NULL);
}

void CMFCRibbonFullscreenBar::AddElement(CRibbonFullscreenButton* pElement, LPCTSTR lpszLabel, BOOL bIsVisible /* = TRUE */)
{
	ASSERT_VALID(this);
	ENSURE(pElement != NULL);
	ASSERT_VALID(pElement);
	ENSURE(lpszLabel != NULL);

	pElement->SetParentRibbonBar(this);
	pElement->SetVisible(bIsVisible);

	m_arElements.Add(pElement);
	m_arElementLabels.Add(lpszLabel);
}

void CMFCRibbonFullscreenBar::AddExtendedElement(CRibbonFullscreenButton* pElement, LPCTSTR lpszLabel, BOOL bIsVisible /* = TRUE */)
{
	ASSERT_VALID(this);
	ENSURE(pElement != NULL);
	ASSERT_VALID(pElement);
	ENSURE(lpszLabel != NULL);

	pElement->SetParentRibbonBar(this);
	pElement->SetVisible(bIsVisible);// = bIsVisible;

	CBCGPRibbonButton* pPane = DYNAMIC_DOWNCAST(CBCGPRibbonButton, pElement);

	if (pPane != NULL)
	{
		ASSERT_VALID(pPane);
		//pPane->m_bIsExtended = TRUE;
	}

	m_arExElements.Add(pElement);
	m_arExElementLabels.Add(lpszLabel);
}

BOOL CMFCRibbonFullscreenBar::RemoveElement(UINT uiID)
{
	ASSERT_VALID(this);

	return TRUE;
}

void CMFCRibbonFullscreenBar::RemoveAll()
{
	ASSERT_VALID(this);

	int i = 0;

	for (i = 0; i < m_arElements.GetSize(); i++)
	{
		delete m_arElements [i];
	}

	m_arElements.RemoveAll();

	for (i = 0; i < m_arExElements.GetSize(); i++)
	{
		delete m_arExElements [i];
	}

	m_arExElements.RemoveAll();

	m_arElementLabels.RemoveAll();
	m_arExElementLabels.RemoveAll();
}

void CMFCRibbonFullscreenBar::RecalcLayout()
{
	ASSERT_VALID(this);
	ASSERT(GetSafeHwnd() != NULL);

	//get the drawing area for the full screen bar
	CRect rect;
	GetClientRect(rect);

	//the size box is based off the size of a scrollbar
	
	CClientDC dc(this);

	CFont *pOldFont = dc.SelectObject(GetFont());
	ENSURE(pOldFont != NULL);

	int xMax = rect.right;

	//Reposition extended(right) elements:
	for (int i=(int)m_arExElements.GetSize()-1; i>=0; i--)
	{
		CBCGPBaseRibbonElement* pElem = m_arExElements[i];
		ASSERT_VALID(pElem);

		pElem->OnCalcTextSize(&dc);

		CSize sizeElem = pElem->GetSize(&dc);

		if (!pElem->IsVisible())
		{
			pElem->SetRect(CRect(0, 0, 0, 0));
		}
		else
		{
			if (pElem->CanBeStretched())
			{
				pElem->SetRect(CRect(xMax-sizeElem.cx, rect.top, xMax, rect.bottom));
			}
			else
			{
				int yOffset = max(0, (rect.Height() - sizeElem.cy)/2);
				pElem->SetRect(CRect(CPoint(xMax-sizeElem.cx, rect.top+yOffset), sizeElem));
			}

			xMax = pElem->GetRect().left;
		}

		pElem->OnAfterChangeRect(&dc);
	}

	// Reposition main(left) elements:
	int x = rect.left;

	BOOL bIsPrevSeparator = TRUE;
	CBCGPBaseRibbonElement* pLastVisibleElem = NULL;

	for (int i=(int)m_arElements.GetSize()-1; i>=0; i--)
	{
		CBCGPBaseRibbonElement* pElem = m_arElements [i];
		ASSERT_VALID(pElem);

		BOOL bIsSeparator = pElem->IsKindOf(RUNTIME_CLASS(CBCGPRibbonSeparator));

		if (bIsSeparator && bIsPrevSeparator)
		{
			pElem->SetRect(CRect(0, 0, 0, 0));
			continue;
		}

		pElem->OnCalcTextSize(&dc);

		CSize sizeElem = pElem->GetSize(&dc);

		if (x + sizeElem.cx > xMax/* || !pElem->m_bIsVisible*/)
		{
			pElem->SetRect(CRect(0, 0, 0, 0));
		}
		else
		{
			if (pElem->CanBeStretched())
			{
				pElem->SetRect(CRect(x, rect.top, x + sizeElem.cx, rect.bottom));
			}
			else
			{
				sizeElem.cy = min(sizeElem.cy, rect.Height());
				int yOffset = max(0, (rect.Height() - sizeElem.cy) / 2);

				pElem->SetRect(CRect(CPoint(x, rect.top + yOffset), sizeElem));
			}

			x += sizeElem.cx;

			//m_cxFree = xMax - x;
			bIsPrevSeparator = bIsSeparator;

			pLastVisibleElem = pElem;
		}

		pElem->OnAfterChangeRect(&dc);
	}

	dc.SelectObject(pOldFont);
}

CSize CMFCRibbonFullscreenBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
	ASSERT_VALID(this);

	CClientDC dc(this);

	CFont* pOldFont = dc.SelectObject(GetFont());
	ENSURE(pOldFont != NULL);

	TEXTMETRIC tm;
	dc.GetTextMetrics(&tm);

	int i = 0;
	int cyMax = tm.tmHeight;

	for (i = 0; i < m_arExElements.GetSize(); i++)
	{
		CBCGPBaseRibbonElement* pElem = m_arExElements [i];
		ASSERT_VALID(pElem);

		pElem->OnCalcTextSize(&dc);
		pElem->SetInitialMode();

		CSize sizeElem = pElem->GetSize(&dc);
		cyMax = max(cyMax, sizeElem.cy + 1);
	}

	for (i = 0; i < m_arElements.GetSize(); i++)
	{
		CBCGPBaseRibbonElement* pElem = m_arElements [i];
		ASSERT_VALID(pElem);

		pElem->OnCalcTextSize(&dc);
		pElem->SetInitialMode();

		CSize sizeElem = pElem->GetSize(&dc);
		cyMax = max(cyMax, sizeElem.cy + 1);
	}

	dc.SelectObject(pOldFont);

	int nMinHeight = 24;

	if (afxGlobalData.GetRibbonImageScale() != 1.)
	{
		nMinHeight = (int)(.5 + afxGlobalData.GetRibbonImageScale() * nMinHeight);
	}

	return CSize(32767, max(nMinHeight, cyMax));
}

HDWP CMFCRibbonFullscreenBar::SetWindowPos(const CWnd* pWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags, HDWP hdwp)
{
	if (cy > 0)
	{
		bool bGet =true;
	}
	return CBCGPBaseControlBar::SetWindowPos(pWndInsertAfter, x, y, cx, cy, nFlags, hdwp);
}

void CMFCRibbonFullscreenBar::OnShowWindow(BOOL bShow, UINT nStatus)
{
	CBCGPRibbonBar::OnShowWindow(bShow, nStatus);

	if (GetParentFrame () != NULL)
	{
		GetParentFrame ()->PostMessage (AFX_WM_CHANGEVISUALMANAGER);
	}
}

CBCGPBaseRibbonElement* CMFCRibbonFullscreenBar::HitTest(CPoint point, BOOL bCheckActiveCategory /* = FALSE */, BOOL bCheckPanelCaption /* = FALSE */)
{
	ASSERT_VALID(this);

	int i = 0;

	for (i = 0; i <(int) m_arElements.GetSize(); i++)
	{
		ASSERT_VALID(m_arElements [i]);

		if (m_arElements [i]->GetRect().PtInRect(point))
		{
			return m_arElements [i]->HitTest(point);
		}
	}

	for (i = 0; i <(int) m_arExElements.GetSize(); i++)
	{
		ASSERT_VALID(m_arExElements [i]);

		if (m_arExElements [i]->GetRect().PtInRect(point))
		{
			return m_arExElements [i]->HitTest(point);
		}
	}

	return NULL;
}

void CMFCRibbonFullscreenBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
{
	//CBCGPRibbonBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
	ASSERT_VALID (this);

	CBCGPRibbonCmdUI state;
	state.m_pOther = this;

	int i = 0;

	for (i = 0; i < (int) m_arElements.GetSize (); i++)
	{
		ASSERT_VALID (m_arElements [i]);
		m_arElements [i]->OnUpdateCmdUI (&state, pTarget, bDisableIfNoHndler);
	}

	for (i = 0; i < (int) m_arExElements.GetSize (); i++)
	{
		ASSERT_VALID (m_arExElements [i]);
		m_arExElements [i]->OnUpdateCmdUI (&state, pTarget, bDisableIfNoHndler);
	}

	// update the dialog controls added to the ribbon
	UpdateDialogControls(pTarget, bDisableIfNoHndler);
}

LRESULT CMFCRibbonFullscreenBar::OnUpdateShadows(WPARAM,LPARAM)
{
	CRect rectWindow;
	GetWindowRect(rectWindow);

	CMFCPopupMenu::UpdateAllShadows(rectWindow);
	return 0;
}